package com.zy.design.pattern.flyweight;
import java.lang.ref.WeakReference;
import	java.util.HashMap;

import java.util.Map;
import java.util.Objects;

/**
 * @author zhaoyi
 * @date 2021/4/20 17:12
 */
public class MyIntegerCache {

    public static Map<Integer,WeakReference<WarpInt>> cache = new HashMap<> ();

    /**
     * 弱引用(弱引用对象是指WeakReference的实例或者其子类的实例)
     * 垃圾回收器在扫描的时候，一旦发现只具有弱引用的对象，不管内存空间是否足够，都会回收它的内存
     * 如果存在强引用同时与之关联，则进行垃圾回收时也不会回收该对象（软引用也是如此）
     * (WeakReference<WarpInt> 有强引用不会被回收,所以当WarpInt被回收时要删除相应的强引用让WeakReference也能在后面被回收)
     *
     * 当一个对象仅仅被弱引用指向, 而没有任何其他强引用指向的时候, 如果这时GC运行, 那么这个对象就会被回收，
     * 不论当前的内存空间是否足够，这个对象都会被回收。(WarpInt被回收)
     *
     *
     * 在对象被回收后，会把弱引用对象，也就是WeakReference对象或者其子类的对象，放入队列ReferenceQueue中，
     * 注意不是被弱引用的对象，被弱引用的对象已经被回收了
     *
     * ***********************************************************************************
     *  IntegerCache 只能缓存事先指定好的整型对象，
     *  借鉴 String 的设计思路，不事先指定需要缓存哪些整型对象，
     *  而是在程序的运行过程中，当用到某个整型对象的时候，创建好放置到 IntegerCache，下次再被用到的时候，直接从 IntegerCache 中返回
     *  并且能够做到在某个对象没有任何代码使用的时候，能被 JVM 垃圾回收机制回收掉
     * **********************************************************************************
     */
    public static Integer get(int i){
        WeakReference<WarpInt> integerData = cache.get(i);
        if (integerData == null){
            WarpInt warpInt = new WarpInt(i);
            integerData = new WeakReference<WarpInt>(warpInt);
            cache.put(i,integerData);
            System.out.println("加入缓存-----");
        }else {
            System.out.println("享元缓存中已经有可直接取");
        }
        return Objects.requireNonNull(integerData.get()).getValue();
    }





    public static void gcRemove(int i){
        System.out.println(" ========= gc从map中移除 弱引用对象 的强引用 "+i);
        cache.remove(i);
    }



}
